#include <bits/stdc++.h>
using namespace std;

#define int long long
#define endl "\n"
#define pb push_back
#define c(a) cout << #a << " = " << a << endl;
#define de(a) for (auto p : a) cout << p << " "; cout << endl;
#define all(a) (a.begin(), a.end())
#define rall(a) (a.rbegin(), a.rend())

#define ls (2 * p)
#define rs (2 * p + 1)

struct Node {
    int l, r;
    int max_val;  // 区间最大值
    int sum;      // 区间和（保留）
    int lazy;     // 懒标记（保留）
};

class segtree {
public:
    vector<Node> tr;
    vector<int> a;
    explicit segtree(int _n) : a(_n + 1), tr((_n + 1) << 2) {};

    void push_up(int p) {
        tr[p].max_val = max(tr[ls].max_val, tr[rs].max_val);
        tr[p].sum = tr[ls].sum + tr[rs].sum;
    }

    void push_down(int p) {
        if (tr[p].lazy) {
            // 更新左子树
            tr[ls].max_val += tr[p].lazy;
            tr[ls].sum += (tr[ls].r - tr[ls].l + 1) * tr[p].lazy;
            tr[ls].lazy += tr[p].lazy;

            // 更新右子树
            tr[rs].max_val += tr[p].lazy;
            tr[rs].sum += (tr[rs].r - tr[rs].l + 1) * tr[p].lazy;
            tr[rs].lazy += tr[p].lazy;

            tr[p].lazy = 0;
        }
    }

    void build(int l, int r, int p = 1) {
        tr[p].l = l;
        tr[p].r = r;
        tr[p].lazy = 0;
        if (l == r) {
            tr[p].max_val = tr[p].sum = a[l];
            return;
        }
        int mid = (l + r) / 2;
        build(l, mid, ls);
        build(mid + 1, r, rs);
        push_up(p);
    }

    int query_max(int l, int r, int p = 1) {
        if (tr[p].l >= l && tr[p].r <= r) {
            return tr[p].max_val;
        }
        push_down(p);
        int mid = (tr[p].l + tr[p].r) / 2;
        int ans = 0;
        if (l <= mid) {
            ans = max(ans, query_max(l, r, ls));
        }
        if (r > mid) {
            ans = max(ans, query_max(l, r, rs));
        }
        return ans;
    }

    int query_sum(int l, int r, int p = 1) {
        if (tr[p].l >= l && tr[p].r <= r) {
            return tr[p].sum;
        }
        push_down(p);
        int mid = (tr[p].l + tr[p].r) / 2;
        int ans = 0;
        if (l <= mid) {
            ans += query_sum(l, r, ls);
        }
        if (r > mid) {
            ans += query_sum(l, r, rs);
        }
        return ans;
    }

    void conditional_update(int x, int val, int p = 1) {
        if (tr[p].l == tr[p].r) {
            tr[p].max_val = val;
            tr[p].sum = val;  // 同时更新sum
            return;
        }
        push_down(p);
        int mid = (tr[p].l + tr[p].r) / 2;
        if (x <= mid) {
            conditional_update(x, val, ls);
        } else {
            conditional_update(x, val, rs);
        }
        push_up(p);
    }

    void update_area(int l, int r, int k, int p = 1) {
        if (tr[p].l >= l && tr[p].r <= r) {
            tr[p].max_val += k;
            tr[p].sum += (tr[p].r - tr[p].l + 1) * k;
            tr[p].lazy += k;
            return;
        }
        push_down(p);
        int mid = (tr[p].l + tr[p].r) / 2;
        if (l <= mid) {
            update_area(l, r, k, ls);
        }
        if (r > mid) {
            update_area(l, r, k, rs);
        }
        push_up(p);
    }
};

void solve() {
    int n, m;
    cin >> n >> m;
    segtree tr(n);
    for (int i = 1; i <= n; i++) {
        cin >> tr.a[i];
    }
    tr.build(1, n);
    while (m--) {
        int op;
        int a, b, k;
        cin >> op;

        if (op == 1) {
            cin >> a >> b >> k;
            tr.update_area(a,b,k,1);
        } else if (op == 2) {
            cin >> a >> b;
            cout<<tr.query_sum(a,b,1)<<endl;
        }
    }
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int q = 1;
    // cin >> q;
    while (q--) solve();
}